﻿namespace com.u3d.bases.loader
{
    using com.game.manager;
    using com.game.module.core;
    using com.game.preloader;
    using com.u3d.bases.debug;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using UnityEngine;

    public class BinLoadMgr : MonoBehaviour
    {
        internal LoadFinishBack errorback;
        private bool isLoading;
        private bool isLoadingScene;
        internal bool isTrace;
        internal LoadFinishBack loadback;
        private Dictionary<string, int> loadFailList;
        private IList<LoadItem> loadingList;
        private LoadItem loadSceneItem;
        private AsyncOperation loadSceneOpt;
        private const int MAX_OFFET_PRIORITY = 0xffff;
        internal int maxNumThread = 1;
        internal int maxNumTry = 3;
        private int offetPriority = 0xffff;
        internal int overtime = 0x1388;
        private LoadProgressBack progresFun;
        internal LoadProgressBack progressback;
        private IList<uint> scenePreloadHistory;
        private IList<LoadItem> waitList;

        internal void addTask(LoadItem task)
        {
            if (((task != null) && (this.waitList.IndexOf(task) == -1)) && (this.loadingList.IndexOf(task) == -1))
            {
                if (this.isOverTrynum(task.url))
                {
                    if (this.isTrace)
                    {
                        Log.error(this, string.Concat(new object[] { "-loadRes() url:", task.url, " 已超过加载重试:", this.maxNumTry, "次！" }));
                    }
                    this.errorback(task.url, null);
                }
                else
                {
                    task.priority = (task.priority * 0xffff) + this.offetPriority;
                    this.offetPriority--;
                    this.waitList.Add(task);
                    if (!this.isLoading)
                    {
                        this.loadNext();
                    }
                }
            }
        }

        private void addTrynum(string url)
        {
            if (this.loadFailList.ContainsKey(url))
            {
                Dictionary<string, int> dictionary;
                string str;
                int num = dictionary[str];
                (dictionary = this.loadFailList)[str = url] = num + 1;
            }
            else
            {
                this.loadFailList.Add(url, 1);
            }
        }

        private void checkOvertimes()
        {
            IEnumerator<LoadItem> enumerator = this.loadingList.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    LoadItem current = enumerator.Current;
                    if (this.isOvertimes(current))
                    {
                        this.addTrynum(current.url);
                    }
                }
            }
            finally
            {
                if (enumerator == null)
                {
                }
                enumerator.Dispose();
            }
        }

        private bool isOvertimes(LoadItem task)
        {
            return ((Environment.TickCount - task.loadBeginTime) >= this.overtime);
        }

        private bool isOverTrynum(string url)
        {
            if (!this.loadFailList.ContainsKey(url))
            {
                return false;
            }
            return (this.loadFailList[url] >= this.maxNumTry);
        }

        [DebuggerHidden]
        private IEnumerator loadFromHttp(LoadItem item)
        {
            return new <loadFromHttp>c__Iterator56 { item = item, <$>item = item, <>f__this = this };
        }

        private void loadNext()
        {
            if (this.loadingList.Count < this.maxNumThread)
            {
                if (this.waitList.Count < 1)
                {
                    if (this.loadingList.Count < 1)
                    {
                        this.isLoading = false;
                        this.offetPriority = 0xffff;
                        if (this.isTrace)
                        {
                            Log.info(this, "-loadNext() 加载器已空闲！");
                        }
                    }
                }
                else
                {
                    LoadItem item = this.waitList[0];
                    this.waitList.RemoveAt(0);
                    this.loadingList.Add(item);
                    base.StartCoroutine(this.loadFromHttp(item));
                    if (this.isTrace)
                    {
                        Log.info(this, "-loadNext() url:" + item.url + " 远程加载开始！");
                    }
                    item = null;
                }
            }
        }

        internal void loadScene(uint mapId, LoadItem item, LoadProgressBack progresFun = null)
        {
            this.loadSceneItem = item;
            this.progresFun = progresFun;
            base.StartCoroutine(this.startLoadScene(mapId, this.loadSceneItem.url));
        }

        private void Start()
        {
            this.waitList = new List<LoadItem>();
            this.loadingList = new List<LoadItem>();
            this.loadFailList = new Dictionary<string, int>();
            this.scenePreloadHistory = new List<uint>();
        }

        [DebuggerHidden]
        private IEnumerator startLoadScene(uint mapId, string url)
        {
            return new <startLoadScene>c__Iterator55 { url = url, mapId = mapId, <$>url = url, <$>mapId = mapId, <>f__this = this };
        }

        internal void unload(LoadItem task)
        {
            if ((task != null) && (this.waitList.IndexOf(task) != -1))
            {
                this.waitList.Remove(task);
            }
        }

        private void Update()
        {
            try
            {
                if ((this.isLoadingScene && (this.progresFun != null)) && (this.loadSceneOpt != null))
                {
                    this.progresFun(null, (int) (this.loadSceneOpt.progress * 100f));
                }
            }
            catch (Exception exception)
            {
                Log.warin(this, exception.Message);
            }
        }

        [CompilerGenerated]
        private sealed class <loadFromHttp>c__Iterator56 : IEnumerator, IDisposable, IEnumerator<object>
        {
            internal object $current;
            internal int $PC;
            internal LoadItem <$>item;
            internal BinLoadMgr <>f__this;
            internal LoadItem item;

            [DebuggerHidden]
            public void Dispose()
            {
                this.$PC = -1;
            }

            public bool MoveNext()
            {
                uint num = (uint) this.$PC;
                this.$PC = -1;
                switch (num)
                {
                    case 0:
                        this.item.www = WWW.LoadFromCacheOrDownload(this.item.url, 1);
                        this.item.loadBeginTime = Environment.TickCount;
                        this.$current = this.item.www;
                        this.$PC = 1;
                        return true;

                    case 1:
                        if (this.<>f__this.isTrace)
                        {
                            Log.info(this.<>f__this, "-loadFromHttp() url:" + this.item.url + " 远程加载完成！");
                        }
                        if (this.<>f__this.loadingList.IndexOf(this.item) != -1)
                        {
                            this.<>f__this.loadingList.Remove(this.item);
                        }
                        if (this.<>f__this.loadFailList.ContainsKey(this.item.url))
                        {
                            this.<>f__this.loadFailList.Remove(this.item.url);
                        }
                        ResPool.instance.addLoadedRes(this.item.url, this.item.www.assetBundle.mainAsset);
                        this.<>f__this.loadback(this.item.url, null);
                        this.item = null;
                        this.<>f__this.loadNext();
                        this.$PC = -1;
                        break;
                }
                return false;
            }

            [DebuggerHidden]
            public void Reset()
            {
                throw new NotSupportedException();
            }

            object IEnumerator<object>.Current
            {
                [DebuggerHidden]
                get
                {
                    return this.$current;
                }
            }

            object IEnumerator.Current
            {
                [DebuggerHidden]
                get
                {
                    return this.$current;
                }
            }
        }

        [CompilerGenerated]
        private sealed class <startLoadScene>c__Iterator55 : IEnumerator, IDisposable, IEnumerator<object>
        {
            internal object $current;
            internal int $PC;
            internal uint <$>mapId;
            internal string <$>url;
            internal BinLoadMgr <>f__this;
            internal int <i>__1;
            internal IPreloader <loader>__3;
            internal IList<SysReadyLoadVo> <preloadList>__2;
            internal int[] <subTypeList>__0;
            internal Task <t>__4;
            internal uint mapId;
            internal string url;

            [DebuggerHidden]
            public void Dispose()
            {
                uint num = (uint) this.$PC;
                this.$PC = -1;
                switch (num)
                {
                    case 1:
                    case 2:
                        try
                        {
                        }
                        finally
                        {
                            this.<>f__this.isLoadingScene = false;
                        }
                        break;
                }
            }

            public bool MoveNext()
            {
                uint num = (uint) this.$PC;
                this.$PC = -1;
                bool flag = false;
                switch (num)
                {
                    case 0:
                        num = 0xfffffffd;
                        break;

                    case 1:
                    case 2:
                        break;

                    default:
                        goto Label_01F1;
                }
                try
                {
                    switch (num)
                    {
                        case 1:
                            if (this.<>f__this.scenePreloadHistory.Contains(this.mapId))
                            {
                                goto Label_01B4;
                            }
                            Log.warin(this.<>f__this, "-startLoadScene() 异步加载场景特效资源" + this.mapId);
                            this.<>f__this.scenePreloadHistory.Add(this.mapId);
                            this.<subTypeList>__0 = new int[] { 1, 5 };
                            this.<i>__1 = 0;
                            goto Label_01A1;

                        case 2:
                            goto Label_0193;

                        default:
                            this.<>f__this.isLoadingScene = true;
                            Log.info(this.<>f__this, "-startLoadScene() 异步加载场景，场景uri： " + this.url);
                            this.<>f__this.loadSceneOpt = Application.LoadLevelAsync(this.url);
                            this.$current = this.<>f__this.loadSceneOpt;
                            this.$PC = 1;
                            flag = true;
                            goto Label_01F3;
                    }
                Label_0107:
                    this.<preloadList>__2 = BaseDataMgr.instance.GetScenePreLoadList(this.mapId, this.<subTypeList>__0[this.<i>__1]);
                    if (this.<preloadList>__2.Count > 0)
                    {
                        this.<loader>__3 = PreloaderFactory.Instance.GetPreLoader(this.<preloadList>__2[0]);
                        this.<t>__4 = CoroutineManager.StartCoroutine(this.<loader>__3.PreloadResourceList(this.<preloadList>__2), true);
                        this.$current = this.<t>__4.Routine;
                        this.$PC = 2;
                        flag = true;
                        goto Label_01F3;
                    }
                Label_0193:
                    this.<i>__1++;
                Label_01A1:
                    if (this.<i>__1 < this.<subTypeList>__0.Length)
                    {
                        goto Label_0107;
                    }
                Label_01B4:
                    if (this.<>f__this.loadSceneItem != null)
                    {
                        this.<>f__this.loadSceneItem.call();
                    }
                }
                finally
                {
                    if (!flag)
                    {
                    }
                    this.<>f__this.isLoadingScene = false;
                }
                this.$PC = -1;
            Label_01F1:
                return false;
            Label_01F3:
                return true;
            }

            [DebuggerHidden]
            public void Reset()
            {
                throw new NotSupportedException();
            }

            object IEnumerator<object>.Current
            {
                [DebuggerHidden]
                get
                {
                    return this.$current;
                }
            }

            object IEnumerator.Current
            {
                [DebuggerHidden]
                get
                {
                    return this.$current;
                }
            }
        }
    }
}

